package org.jslaughter.level;

import java.util.ArrayList;

import org.jslaughter.camera.plugin.SHMShakyCamEffect;
import org.jslaughter.camera.plugin.SmoothFollowPlugin;
import org.jslaughter.component.ai.BehaviourImpl;
import org.jslaughter.component.inventory.WeaponManager;
import org.jslaughter.event.eventtype.DamageEvent;
import org.jslaughter.event.eventtype.DeathEvent;
import org.jslaughter.event.eventtype.DeathListener;
import org.newdawn.slick.Font;
import org.nvframe.camera.Camera;
import org.nvframe.component.ai.Behaviour;
import org.nvframe.component.ai.Behaviour.BEHAVIOUR_TYPE;
import org.nvframe.component.state.Position;
import org.nvframe.entity.Entity;
import org.nvframe.event.EventService;
import org.nvframe.event.eventtype.RenderEvent;
import org.nvframe.event.eventtype.RenderListener;
import org.nvframe.event.eventtype.UpdateEvent;
import org.nvframe.event.eventtype.UpdateListener;
import org.nvframe.exception.NVFrameException;
import org.nvframe.factory.EntityFactory;
import org.nvframe.manager.ConfigManager;
import org.nvframe.manager.EntityManager;
import org.nvframe.manager.InputManager;
import org.nvframe.manager.ResourceManager;

public class Level1 extends Level implements DeathListener, UpdateListener, RenderListener {
	
	private Font verdana;
	
	private boolean gameOver = false;
	private boolean gameWon = false;
	
	public void start() {
		Entity player = EntityManager.getInstance().getEntity("ent_player");
		
		WeaponManager weaponManager = (WeaponManager) player.getComponent(WeaponManager.class);
		weaponManager.addWeapon("ent_weapon_pistol");
		
		// add a camera that follows player
		Camera camera = Camera.getInstance();
		camera.addPlugin(new SHMShakyCamEffect(player));
		camera.addPlugin(new SmoothFollowPlugin(player));
		
		// prefetch fonts for later use
		try {
			verdana = ResourceManager.getInstance().getFont("fnt_verdana_15");
		} catch (NVFrameException e) {
			e.printStackTrace();
		}
		
		EventService.getInstance().addEventListener(this);
	}

	@Override
	public void onDeath(DeathEvent event) {
		// player death?
		if(event.getEntity().getId().equals("ent_player"))
			gameOver = true;
		
		// all enemies death?
		int spawnerCount = EntityManager.getInstance().getInstancesCount("ent_enemyspawner1", true);
		spawnerCount += EntityManager.getInstance().getInstancesCount("ent_enemyspawner2", true);
		int enemyCount = EntityManager.getInstance().getInstancesCount("ent_enemy1", true);
		enemyCount += EntityManager.getInstance().getInstancesCount("ent_enemy2", true);
		
		// entity from event is also death but EntityManager doesn't know this yet
		// that's cause DeathEvent gets fired before entity.removed() is called
		Entity entity = event.getEntity();
		if(entity.getId().equals("ent_enemyspawner1") || entity.getId().equals("ent_enemyspawner2"))
			spawnerCount--;
		if(entity.getId().equals("ent_enemy1") || entity.getId().equals("ent_enemy2"))
			enemyCount--;

		if(spawnerCount == 0 && enemyCount == 0) 
			gameWon = true;
	}

	@Override
	public void onUpdate(UpdateEvent event) {
		
		// add a zombieteam key
		if (event.getGc().getInput().isKeyPressed(
				InputManager.getInstance().getInput("player_addzombieteam"))) {
			
			// add a zombieteam
			Entity player = EntityManager.getInstance().getEntity("ent_player");
			Position positionComp = (Position) player.getComponent(Position.class);
			
			for(int i = 0; i < 5; i++) {
				Entity zombie;
				try {
					zombie = EntityFactory.getInstance().getEntityFromPrototype("ent_enemy2");
					
					Behaviour zombieBehaviour  = (Behaviour) zombie.getComponent(Behaviour.class);
					Position zombiePosition  = (Position) zombie.getComponent(Position.class);
					zombieBehaviour.setTeam("ALLIES");
					
					zombiePosition.setXY(positionComp.getXY().x + 40, positionComp.getXY().y + 40);
				} catch (NVFrameException e) {
					e.printStackTrace();
				}
			}
		}
	
		// kill all entities key
		if (event.getGc().getInput().isKeyPressed(
				InputManager.getInstance().getInput("player_killenemies"))) {
			
			ArrayList<Entity> entities = (ArrayList<Entity>) EntityManager.getInstance().getEntities();
			Entity player = EntityManager.getInstance().getEntity("ent_player");
			BehaviourImpl behaviour = (BehaviourImpl) player.getComponent(Behaviour.class);
			
			for(Entity entity : entities) {
				if(behaviour.getBehaviourTowards(entity) == BEHAVIOUR_TYPE.HOSTILE)
					EventService.getInstance().fireEvent(new DamageEvent(player, entity, 9999), entity);
			}
		}
	}
	
	public void onRender(RenderEvent event) {
		if(gameWon)
			verdana.drawString(400, 400, "WOHOO YOU DEFEATED ZHE ZOMBIEZ!");
		else if(gameOver)
			verdana.drawString(400, 400, "GAME OVER MAN, YOU FAILED BIG TIME!");
		
		if(ConfigManager.getInstance().getActive("debugMode"))
			verdana.drawString(10, 40, "DEBUG MODE! Some nifty keys: \n\n" +
					"F1 - switch debugmode on/off \n" +
					"F2 - vsync \n" +
					"F3 - draw physics bodies (still has a few bugs :p) \n" +
					"F4 - draw entity positions \n" +
					"F5 - print entitylist in console \n" +
					"F6 - sound on/off \n" +
					"F7 - print all keybindings in console \n" +
					"F8 - draw all entity names \n" +
					"\n" +
					"F9 - add friendly zombies \n" +
					"F10 - switch friendly fire \n" +
					"F11 - kill all enemies \n" +
					"\n" +
					"P - pauzes the game \n" +
					"L SHIFT - run, will be removed in productionversion");
	}
	
}
